
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.io.Connection;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.StringItem;

/**
 *
 * @author nextor
 */
public class WSConnection extends Thread {

    private StreamConnection client;
    Vector files;
    Vector images;
    private Form form;
    private final Vector filepool;
    long last = 0;
    private static final int CHUNK_SIZE = 1024;
    public static final int FILE_INDEX = 1;
    public static final int FILE_CSS = 2;
    public static final int FILE_JS = 3;
    public static final int FILE_NEXT = 4;
    public static final int FILE_PAUSE = 5;
    public static final int FILE_PREVIOUS = 6;
    public static final int FILE_OTHER = 7;
    public static final int FILE_PLAY = 8;
    public static final int FILE_INDEX2 = 9;
    public static final int FILE_PHOTO_INDEX =10;
    boolean finalizable = true;

    public WSConnection(StreamConnection c, Vector files,Vector images,Form form, Vector filepool, int ccounter) {
        super("" + ccounter);
        client = c;
        this.files = files;
        this.form = form;
        this.filepool = filepool;
        this.images = images;
    }

    /**
     * Handles client request.
     */
    public void run() {
        InputStream s = null;
        PrintStream pout = null;
        OutputStream out = null;
        StringBuffer b = new StringBuffer();
        // FileConnection sc = null;
        last = System.currentTimeMillis();
        try {
            // f.append("Opening client");
            s = client.openInputStream();
            // f.append("Client appening waiting to write");
            //Ignore reading request to reduce the amount of data
            //transfered to Phone.
            try {
                Thread.sleep(700);
            } catch (Exception e) {
                e.printStackTrace();
            }
            int ch = 0;
            //read headers only;
            int lastC = 0;
            int counter = 0;
            while ((ch = s.read()) != -1 && s.available() > 0) {
                b.append((char) ch);
                if(ch == '\r')
                {
                    counter++;
                }
                else if(ch=='\n' && lastC == '\r')
                {
                    counter++;
                }
                else
                    counter = 0;
                    
                if(counter==4)
                {
                    form.append("Encontro el header");
                    break;
                }
            }
            System.out.println(b.toString());
            out = client.openOutputStream();
            pout = new PrintStream(out);
            last = System.currentTimeMillis();
            int file = isIndex(b.toString());
            if (file != FILE_OTHER) {
                InputStream in = null;
                finalizable = false;
                try {
                    // int bb= 0;
                    form.append("filetype "+file);
                    switch (file) {
                        case FILE_PHOTO_INDEX:
                            this.writeHeaders("text/html; charset=utf-8",-1,null,pout);
                            this.writePhotoIndex(images, pout);
                            break;
                        case FILE_INDEX2:
                            this.writeHeaders("text/html; charset=utf-8", -1, null, pout);
                            writeIndex2(files,pout);
                            break;
                        case FILE_INDEX:
                            this.writeHeaders("text/html; charset=utf-8", -1, null, pout);
                            writeIndex(files, pout);

                            break;
                        case FILE_CSS:
                            in = this.getClass().getResourceAsStream("/PagePlayer.css");
                            this.writeHeaders("text/css", -1, null, pout);
                            break;
                        case FILE_JS:

                            in = this.getClass().getResourceAsStream("/PagePlayer.js");
                            this.writeHeaders("text/javascript", -1, null, pout);
                            break;
                        case FILE_NEXT:
                            in = this.getClass().getResourceAsStream("/next.png");
                            this.writeHeaders("image/png", -1, null, pout);
                            break;
                        case FILE_PREVIOUS:
                            in = this.getClass().getResourceAsStream("/previous.png");
                            this.writeHeaders("image/png", -1, null, pout);
                            break;
                        case FILE_PAUSE:
                            in = this.getClass().getResourceAsStream("/pause.png");
                            this.writeHeaders("image/png", -1, null, pout);
                            break;
                        case FILE_PLAY:
                            in = this.getClass().getResourceAsStream("/play.png");
                            this.writeHeaders("image/png", -1, null, pout);
                            break;

                    }
                    if (file != FILE_INDEX2 && file != FILE_INDEX) {
                        byte[] bb = new byte[1024];
                        int len = 0;
                        while ((len = in.read(bb, 0, 1024)) != -1) {
                            out.write(bb, 0, len);
                        }
                    }
                } catch (Exception _e) {
                    form.append(_e.toString());
                } finally {
                    this.closeClosable(s);
                    this.closeClosable(out);
                    this.closeClosable(pout);
                    this.closeClosable(client);

                }
                return;
            }

            //GET the name of file

            String[] mypath = split(b.toString(), "\n");
            String[] get = split(mypath[0], " ");
            
            int number = 0;
            if(get[1].endsWith(".jpg"))
            {
                String xx= get[1].substring(1);
                String strn = xx.substring(0,xx.indexOf('.'));
                number = Integer.parseInt(strn);
            }
            else
               number = Integer.parseInt(get[1].substring(1));
            
            String filename = null;
      
            if(get[1].endsWith("mp3"))
             filename = (String) files.elementAt(number);
            else
                filename = (String) images.elementAt(number);
                
            form.append(new StringItem("Step", "streaming song " + decode(filename)));

            int len = 0;

            last = System.currentTimeMillis();

            FileConnection fileConn =
                    (FileConnection) Connector.open(filename, Connector.READ);
            // load the image data in memory
            // Read data in CHUNK_SIZE chunks

            InputStream fis = fileConn.openInputStream();
            long overallSize = fileConn.fileSize();
            last = System.currentTimeMillis();
            int length = 0;
            byte[] data = new byte[CHUNK_SIZE];
            byte[] imageData = new byte[0];
           
            try {
                if(get[1].endsWith("mp3"))
                    this.writeHeaders("audio/mpeg", overallSize, "file.mp3", pout);
                else
                    this.writeHeaders("image/jpeg", overallSize, "file.jpg", pout);
                
                while (length < overallSize) {

                    int readAmount = fis.read(data, 0, CHUNK_SIZE);
                    length += readAmount;
                    out.write(data, 0, readAmount);
                    last = System.currentTimeMillis();
                }
            } catch (IOException e) {
                form.append(e.toString());
                if(form.size()>5)
                    form.delete(0);
                    form.delete(0);
            }
            if(form.size()>3)
                    form.delete(0);
                    form.delete(0);
            fis.close();
            fileConn.close();


        } catch (Throwable ioe) {
            //Handle Exceptions any other way you like.
            //No-op
            form.append(new StringItem("Eliminated", "Exception " + ioe.toString()));
            ioe.printStackTrace();
            // f.append(""+ioe.toString());
        } finally {




            this.closeClosable(s);
            this.closeClosable(out);
            this.closeClosable(pout);
            this.closeClosable(client);
            // this.closeClosable(sc);


            if (form.size() > 2) {
                form.delete(2);
            }
        }

        form = null;
    }

   
    public int isIndex(String b) {
        String[] s = split(b, "\n");
        String[] get = split(s[0], " ");
        if (get.length > 0) {
            if( get[1].compareTo("/photos.html") ==0 )
                    return FILE_PHOTO_INDEX;
            if (get[1].compareTo("/index.html") == 0 || get[1].compareTo("/") == 0) {
                return FILE_INDEX;
            }

            if (get[1].compareTo("/PagePlayer.css") == 0) {
                return FILE_CSS;
            }
            if (get[1].compareTo("/PagePlayer.js") == 0) {
                return FILE_JS;
            }
            if (get[1].compareTo("/next.png") == 0) {
                return FILE_NEXT;
            }
            if (get[1].compareTo("/pause.png") == 0) {
                return FILE_PAUSE;
            }
            if (get[1].compareTo("/previous.png") == 0) {
                return FILE_PREVIOUS;
            }
            if (get[1].compareTo("/play.png") == 0) {
                return FILE_PLAY;
            }
            if (get[1].compareTo("/index2.html") == 0) {
                return FILE_INDEX2;
            }
        }

        return FILE_OTHER;
    }

    public void closeClosable(OutputStream c) {
        if (c != null) {
            try {
                c.close();
            } catch (Exception e) {
            }
        }
    }

    public void closeClosable(InputStream c) {
        if (c != null) {
            try {
                c.close();
            } catch (Exception e) {
            }
        }
    }

    public void closeClosable(Connection c) {
        if (c != null) {
            try {
                c.close();
            } catch (Exception e) {
            }
        }
    }

    public String[] split(String splitStr, String delimiter) {

        StringBuffer token = new StringBuffer();
        Vector tokens = new Vector();

// split
        char[] chars = splitStr.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (delimiter.indexOf(chars[i]) != -1) {
// we bumbed into a delimiter
                if (token.length() > 0) {
                    tokens.addElement(token.toString());
                    token.setLength(0);
                }
            } else {
                token.append(chars[i]);
            }
        }
// don't forget the "tail"...
        if (token.length() > 0) {
            tokens.addElement(token.toString());
        }

// convert the vector into an array
        String[] splitArray = new String[tokens.size()];
        for (int i = 0; i < splitArray.length; i++) {
            splitArray[i] = (String) tokens.elementAt(i);
        }
        return splitArray;
    }

    public Hashtable getHeaders(String str)
    {
        Hashtable t = new Hashtable();
        String [] headers = split(str.trim(),"\n");
        for(int i=0;i<headers.length;i++)
        {
            int index = headers[i].indexOf(':');
            String key = headers[i].substring(0, index);
            String value = headers[i].substring(index+1).trim();
            t.put(key, value);
        }
        return t;
    }
    public String getPath(String str) {
        int i = str.lastIndexOf('/');
        if (i == -1) {
            return str;
        }

        return str.substring(0, i + 1);
    }

    public String getFilename(String str) {
        int i = str.lastIndexOf('/');
        if (i == -1) {
            return str;
        }

        return str.substring(i + 1, str.length());
    }

    public void gotoFile(FileConnection f, String path) throws IOException {

        while (!path.startsWith(f.getPath())) {
            form.append("../");
            f.setFileConnection("..");
        }


        String s = path.substring(path.length());
        form.append(new StringItem("current path is " + f.getPath(), "" + s + " final path is" + path));
        f.setFileConnection(s);

    }

    public static String decode(String s) {

        ByteArrayOutputStream out = new ByteArrayOutputStream(s.length());

        for (int i = 0; i < s.length(); i++) {
            int c = (int) s.charAt(i);
            if (c == '+') {
                out.write(' ');
            } else if (c == '%') {
                int c1 = Character.digit(s.charAt(++i), 16);
                int c2 = Character.digit(s.charAt(++i), 16);
                out.write((char) (c1 * 16 + c2));
            } else {
                out.write(c);
            }
        } // end for

        return out.toString();

    }

    public void writeHeaders(String type, long size, String name, PrintStream p) throws IOException {

        String header = "HTTP/1.1 200 OK \r\n";
        if (type != null) {
            header += "Content-Type: " + type + " \r\n";
        }
        if (size != -1) {
            header += "Content-Length: " + size + " \r\n";
        }
        if (name != null) {
            header += "Content-Disposition: inline; filename=" + name + " \r\n";
        }
        header += "Connection: close \r\n\r\n";
        p.write(header.getBytes());
    }

    public void writePhotoIndex(Vector files, PrintStream out) throws IOException
    {
        StringBuffer b = new StringBuffer();
        b.append("<html><body>\n");
        Enumeration e = files.elements();
        int i=0;
        while(e.hasMoreElements())
        {
            b.append("<a href=\"");
            b.append(i++);
            b.append(".jpg");
            b.append("\">");
            b.append(decode((String)e.nextElement()));
            b.append("</a><br>");        
                    
        }
        b.append("</body></html>\n");
        out.write(b.toString().getBytes());
    }
    public void writeIndex(Vector files, PrintStream out) throws IOException {
        String st = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""
                + "\"http://www.w3.org/TR/html4/loose.dtd\"> "
                + "<html>"
                + "<head>"
                + "	<title>JavaScript Audio Player</title>"
                + "	<script >";
        out.write(st.getBytes());
        InputStream in = this.getClass().getResourceAsStream("/PagePlayer.js");
        byte[] bb = new byte[1024];
        int len = 0;
        while ((len = in.read(bb, 0, 1024)) != -1) {
            out.write(bb, 0, len);
        }
        out.write("</script><style type=\"text/css\">".getBytes());
        in = this.getClass().getResourceAsStream("/PagePlayer.css");
        len = 0;
        while ((len = in.read(bb, 0, 1024)) != -1) {
            out.write(bb, 0, len);
        }
        out.write("</style>".getBytes());

        st = "</head>"
                + "<body onload=\"onPagePlayerLoad();\" onresize=\"PagePlayerSetDescriptionHeight();\">"
                + "	<ul id=\"PagePlayer\">";
        out.write(st.getBytes());
        Enumeration e = files.elements();
        int count = 0;
        StringBuffer buff = new StringBuffer();
        while (e.hasMoreElements()) {
            String path = (String) e.nextElement();
            String name = decode(path.substring(path.lastIndexOf('/')));
            buff.append("<li><h3>");
            buff.append(name);
            buff.append("</h3>");
            buff.append("<p> ");
            buff.append(name);
            buff.append("</p>");
            buff.append("<a href=\"/");
            buff.append(count);
            buff.append("\">Download</a>");
            buff.append("</li>\n");
            out.write(buff.toString().getBytes());
            buff.setLength(0);
            count++;
        }
        st = "</ul>"
                + "<script type=\"text/javascript\">"
                + "	//set some PagePlaer variables\n"
                + "	audio_volume=0.85; //default is 0.7\n"
                + "	autoplay=false;\n"
                + "	//when ignore_description is true, remember to adjust the CSS accordingly\n"
                + "	ignore_description=false;\n"
                + "	PagePlayer(\"PagePlayer\");\n"
                + "	/*what happens when the page is loaded?"
                + "	please see the \"body\" tag"
                + "	*/\n"
                + "</script>"
                + "<div id=\"message\"></div>"
                + "</body>"
                + "</html>";
        out.write(st.getBytes());
    }

    public void writeIndex2(Vector files, PrintStream out) throws IOException {
        String st = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""
                + "\"http://www.w3.org/TR/html4/loose.dtd\"> "
                + "<html>"
                + "<head>"
                + "	<title>JavaScript Audio Player</title>"
                + "<script src=\"PagePlayer.js\" type=\"text/javascript\"></script>\n"
                + "<link rel=\"stylesheet\" type=\"text/css\" href=\"PagePlayer.css\">\n";
        out.write(st.getBytes());

        st = "</head>"
                + "<body onload=\"onPagePlayerLoad();\" onresize=\"PagePlayerSetDescriptionHeight();\">"
                + "	<ul id=\"PagePlayer\">";
        out.write(st.getBytes());
        Enumeration e = files.elements();
        int count = 0;
        StringBuffer buff = new StringBuffer();
        while (e.hasMoreElements()) {
            String path = (String) e.nextElement();
            String name = decode(path.substring(path.lastIndexOf('/')));
            buff.append("<li><h3>");
            buff.append(name);
            buff.append("</h3>");
            buff.append("<p> ");
            buff.append(name);
            buff.append("</p>");
            buff.append("<a href=\"/");
            buff.append(count);
            buff.append("\">Download</a>");
            buff.append("</li>\n");
            out.write(buff.toString().getBytes());
            buff.setLength(0);
            count++;
        }
        st = "</ul>"
                + "<script type=\"text/javascript\">"
                + "	//set some PagePlaer variables\n"
                + "	audio_volume=0.85; //default is 0.7\n"
                + "	autoplay=false;\n"
                + "	//when ignore_description is true, remember to adjust the CSS accordingly\n"
                + "	ignore_description=false;\n"
                + "	PagePlayer(\"PagePlayer\");\n"
                + "	/*what happens when the page is loaded?"
                + "	please see the \"body\" tag"
                + "	*/\n"
                + "</script>"
                + "<div id=\"message\"></div>"
                + "</body>"
                + "</html>";
        out.write(st.getBytes());
    }
   
}
